A union in C is a special data type that allows storing different data types in the same memory location. Unlike structures, where each member has its own memory location, union members share the same memory location.
Key Point: The size of a union is determined by the size of its largest member. Only one member can contain a value at any given time.
Unions are useful when you need to use the same memory location for different purposes or when you want to save memory by reusing the same memory space for different types of data.
2. Union Definition and Declaration
2.1 Union Syntax
Definition: The union keyword is used to define a union.
Syntax:
union union_name {
data_type member1;
data_type member2;
// ... more members
};
Example:
// Define a union that can store different data types
union Data {
int i;
float f;
char str[20];
};
2.2 Union Declaration
After defining a union, you can declare variables of that union type.
Example:
#include <stdio.h>
#include <string.h>
// Define the union
union Data {
int i;
float f;
char str[20];
};
int main() {
// Declare a union variable
union Data data;
return 0;
}
2.3 Union Initialization
Union variables can be initialized, but only the first member can be initialized directly.
Example:
#include <stdio.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
// Initialize the first member of the union
union Data data = {10};
printf("data.i = %d\n", data.i);
return 0;
}
Output:
data.i = 10
3. Accessing Union Members
Union members are accessed using the dot (.) operator. However, only one member should be accessed at a time as they share the same memory location.
Example:
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data;
// Store integer
data.i = 10;
printf("data.i : %d\n", data.i);
// Store float - this will corrupt the previous value
data.f = 220.5;
printf("data.f : %.2f\n", data.f);
// Store string - this will corrupt the previous value
strcpy(data.str, "C Programming");
printf("data.str : %s\n", data.str);
// Demonstrate that only one value is stored at a time
printf("data.i after storing string: %d (garbage value)\n", data.i);
printf("data.f after storing string: %.2f (garbage value)\n", data.f);
return 0;
}
Output:
data.i : 10
data.f : 220.50
data.str : C Programming
data.i after storing string: 1917853763 (garbage value)
data.f after storing string: 4122360580327794900000000000000.00 (garbage value)
4. Memory Allocation in Unions
Unions allocate memory equal to the size of their largest member. All members share this same memory space.
Example:
#include <stdio.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data;
printf("Memory size occupied by data : %lu bytes\n", sizeof(data));
printf("Size of int: %lu bytes\n", sizeof(int));
printf("Size of float: %lu bytes\n", sizeof(float));
printf("Size of char[20]: %lu bytes\n", sizeof(char[20]));
return 0;
}
Output:
Memory size occupied by data : 20 bytes
Size of int: 4 bytes
Size of float: 4 bytes
Size of char[20]: 20 bytes
Memory Visualization:
For the union Data defined above, the memory allocation would look like this:
Memory Address Member Value (example)
0x1000 - 0x1003 i 10 (when storing integer)
0x1000 - 0x1003 f 220.5 (when storing float)
0x1000 - 0x1013 str "C Programming" (when storing string)
All members share the same starting memory address (0x1000 in this example).
5. Union vs Structure
Feature
Union
Structure
Keyword
union
struct
Memory Allocation
Members share memory
Each member has separate memory
Total Size
Size of largest member
Sum of sizes of all members (plus padding)
Member Access
Only one member can be accessed at a time
All members can be accessed independently
Memory Efficiency
High (memory is reused)
Low (each member uses separate memory)
Use Case
When only one member is needed at a time
When all members need to be stored simultaneously
#include <stdio.h>
// Define a union and a structure with same members
union UnionData {
int i;
float f;
char str[20];
};
struct StructData {
int i;
float f;
char str[20];
};
int main() {
union UnionData u;
struct StructData s;
printf("Size of union: %lu bytes\n", sizeof(u));
printf("Size of structure: %lu bytes\n", sizeof(s));
return 0;
}
Output:
Size of union: 20 bytes
Size of structure: 28 bytes
6. typedef with Unions
The typedef keyword can be used with unions to create an alias, making the code cleaner and easier to read.
Example:
#include <stdio.h>
#include <string.h>
// Using typedef to create an alias for union
typedef union {
int i;
float f;
char str[20];
} Data;
int main() {
// Now we can use Data instead of union Data
Data data;
Note: Using typedef with unions makes the code cleaner and easier to read, as you don't have to use the union keyword every time you declare a variable.
7. Practical Applications of Unions
7.1 Variant Data Types
Unions are often used to implement variant data types where a value can be one of several types.
#include <stdio.h>
#include <string.h>
typedef enum { INT, FLOAT, STRING } Type;
typedef struct {
Type type;
union {
int i;
float f;
char str[20];
} value;
} Variant;
void printVariant(Variant v) {
switch(v.type) {
case INT:
printf("Integer: %d\n", v.value.i);
break;
case FLOAT:
printf("Float: %.2f\n", v.value.f);
break;
case STRING:
printf("String: %s\n", v.value.str);
break;
}
}
Unions are useful for accessing hardware registers that can be interpreted in different ways.
#include <stdio.h>
// Example: A 32-bit register that can be accessed as a whole or as bytes
typedef union {
unsigned int value;
struct {
unsigned char byte0;
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
} bytes;
} HardwareRegister;
int main() {
HardwareRegister reg;
reg.value = 0x12345678;